#include "command.h"
#include <mysql/mysql.h>
#include <openssl/sha.h>
#include <string.h>
#include <sys/types.h>
int getHash(char *fileName,char *hash){
    SHA_CTX ctx;
    SHA1_Init(&ctx);
    char buf[4096];
    int fd=open(fileName,O_RDWR);
    while(1){
        memset(buf,0,4096);
        ssize_t sret=read(fd,buf,sizeof(buf));
        if(sret==0){
            break;
        }
        SHA1_Update(&ctx,buf,sret);
    }
    unsigned char md[20]={0};
    SHA1_Final(md,&ctx);
    char sha1str[41]={0};
    for(int i=0;i<20;++i){
        char temp[3]={0};
        sprintf(temp,"%02X",md[i]);
        strcat(sha1str,temp);
    }
    strcpy(hash,sha1str);
    return 0;
}

int commandReturn(int socketFd,char *fileName,commandType ret){
    // 接收服务端对命令路径的判断，以及执行结果
    // 返回TRUE正确且完成，PATHERROR 路径错误，GET下载命令 PUT 上传命令
    if(ret==PUTS){
        // 客户端上传文件，客户端发送哈希值
        // 
        train_t train;
        train.command=PUTS;
        commandType t=PUTS;
        train.argvSize=strlen(fileName);
        strcpy(train.argv,fileName);
        send(socketFd,&t,sizeof(int),MSG_WAITALL);
        recv(socketFd,&t,sizeof(int),MSG_WAITALL);
        send(socketFd,&train.argvSize,sizeof(int),MSG_WAITALL);
        send(socketFd,train.argv,train.argvSize,MSG_WAITALL);
        recv(socketFd,&t,sizeof(int),MSG_WAITALL);
        char hash[41]={0};
        char flag;
        getHash(fileName,hash);
        send(socketFd,&hash,sizeof(hash),0);
        /* recv(socketFd,&flag,sizeof(char),MSG_WAITALL); */
        /* if(flag=='0'){ */
        /* printf("开始发送文件\n"); */
        do{
            sendFileToServer(socketFd,fileName);
            int flag=1;
            recv(socketFd,&flag,sizeof(int),MSG_WAITALL);
        }while(flag);
        /* } */
        /* else{ */
        /* // */
        /* printf("触发极速秒传\n"); */
        /* } */
        printf("上传成功\n");
    }
    else if(ret==0){
        printf("超时断开\n");
        return 1;
    }
    else if(ret==GETS){

        printf("下载文件\n");
        // 客户端下载文件，客户端接收
        char hash[41]={0};
        char localHash[41]={0};
        int hashLen;
        recv(socketFd,&hashLen,sizeof(int),MSG_WAITALL);
        recv(socketFd,hash,hashLen,MSG_WAITALL);
        do{
            memset(localHash,0,sizeof(localHash));
            recvFileFromServer(socketFd,fileName);
            getHash(fileName,localHash);
            int flag=1;
            if(strcmp(hash,localHash)==0){
                flag=0;
                send(socketFd,&flag,sizeof(int),0);
                break;
            }
            else{
                char tmp[64]={0};
                sprintf(tmp,"%s.rcd",fileName);
                if (remove(fileName) == 0) {
                } else {
                }   
                if (remove(tmp) == 0) {                                                                                                           
                    printf("文件删除成功\n");
                } else {
                    perror("删除文件失败");
                }   
                send(socketFd,&flag,sizeof(int),0);
                printf("flag=%d\n",flag);
            }
        }while(1);
        printf("下载成功\n");
    }
    else if(ret==ERROR){
        // 路径错误，重新输入
        printf("路径错误，请重新输入命令\n");
    }
    else if(ret==PWD){
        // 接收路径长度
        int len;
        char path[64]={0};
        recv(socketFd,&len,sizeof(int),MSG_WAITALL);
        if(len!=-1){
            recv(socketFd,path,len,MSG_WAITALL);
        }
        printf("当前路径为%s\n",path);
    }
    else if(ret==LS){
        // 接收文件数量
        my_ulonglong rowsCnt;
        recv(socketFd,&rowsCnt,sizeof(rowsCnt),MSG_WAITALL);
        printf("目录中共有 %"PRIu64"个文件（非隐藏）:\n", rowsCnt);
        for(my_ulonglong i=0;i<rowsCnt;++i){
            int len;
            char name[32]={0};
            char type[8]={0};
            recv(socketFd,&len,sizeof(int),MSG_WAITALL);
            recv(socketFd,name,len,MSG_WAITALL);
            recv(socketFd,&len,sizeof(int),MSG_WAITALL);
            recv(socketFd,type,len,MSG_WAITALL);
            if(name[0]){
                printf("%s", name);
            }
            if(type[0]){
                printf("(%s)   ", type);
            }
        }
        printf("\n");
    }
    else if(ret==TREE){
    }
    else if(ret==CD){
    }
    else if(ret==MKDIR){
    }
    else if(ret==RMDIR){
    }
    else if(ret==REMOVE){
    }
    return 0;
}

int commandRecognition(char *buf,train_t *train){
    char *savePtr=NULL;
    char *cmdtype=NULL;
    char *cmdpath=NULL;
    cmdtype=strtok_r(buf," ",&savePtr);
    cmdpath=strtok_r(NULL," ",&savePtr);
    if(strcmp(cmdtype,"cd")==0){
        train->command=CD;
    }
    else if(strcmp(cmdtype,"pwd")==0){
        train->command=PWD;
    }
    else if(strcmp(cmdtype,"ls")==0){
        train->command=LS;
    }
    else if(strcmp(cmdtype,"puts")==0){
        train->command=PUTS;
        train->argvSize=strlen(cmdpath);
        memcpy(train->argv,cmdpath,strlen(cmdpath));
        return PUTS;
    }
    else if(strcmp(cmdtype,"gets")==0){
        train->command=GETS;
        train->argvSize=strlen(cmdpath);
        memcpy(train->argv,cmdpath,strlen(cmdpath));
        return GETS;
    }
    else if(strcmp(cmdtype,"rm")==0){
        train->command=REMOVE;
    }
    else if(strcmp(cmdtype,"rmdir")==0){
        train->command=RMDIR;
    }
    else if(strcmp(cmdtype,"mkdir")==0){
        train->command=MKDIR;
    }
    else if(strcmp(cmdtype,"tree")==0){
        train->command=TREE;
    }
    else{
        printf("命令无效,请重新输入\n");
        return -1;
    }
    if(cmdpath){
        train->argvSize=strlen(cmdpath);
        memcpy(train->argv,cmdpath,strlen(cmdpath));
    }
    else{
        train->argvSize=0;
    }
    return 0;
}
